import random


class CellGenetics:
    # 基因位段字典，定义每个性状对应的基因段起始和结束位置
    GENE_SEGMENTS = {
        'autotrophic_heterotrophic': (0, 6),
        'defense_offense': (6, 12),
        'static_motion': (12, 18),
        'long_life_short_life': (18, 24),
        'attract_repel': (24, 30),

        'division_threshold': (40, 50),
        'low_metabolism_high_metabolism': (58, 64),
        'mutation_rate': (64, 70),
        'size': (70, 76),
        'move_energy_cost': (76, 82)
    }

    def __init__(self, genetic_code=None, mutation_rate=1):
        self.genetic_code = genetic_code if genetic_code else self._generate_random_code()
        self.mutation_rate = mutation_rate

    def _generate_random_code(self):
        # 生成一个随机的基因序列，长度为92位
        code = [random.choice([0, 1]) for _ in range(92)]


        # 初始化代谢速度参数，范围为[0, 63]
        metabolism_rate = random.randint(0, 63)
        metabolism_rate_binary = format(metabolism_rate, '06b')
        for i in range(58, 64):
            code[i] = int(metabolism_rate_binary[i - 58])
        # 初始化突变率参数，范围为[0, 63]
        mutation_rate = random.randint(0, 63)
        mutation_rate_binary = format(mutation_rate, '06b')
        for i in range(64, 70):
            code[i] = int(mutation_rate_binary[i - 64])
        # 初始化大小参数，范围为[0, 63]
        size = random.randint(0, 63)
        size_binary = format(size, '06b')
        for i in range(70, 76):
            code[i] = int(size_binary[i - 70])
        # 初始化分裂阈值参数，范围为[0, 1023]
        division_threshold = random.randint(0, 1023)
        division_threshold_binary = format(division_threshold, '010b')
        for i in range(40, 50):
            code[i] = int(division_threshold_binary[i - 40])
            
        # 初始化移动能耗参数，范围为[0, 63]
        move_energy_cost = random.randint(0, 63)
        move_energy_cost_binary = format(move_energy_cost, '06b')
        for i in range(76, 82):
            code[i] = int(move_energy_cost_binary[i - 76])
        return code

    @staticmethod
    def crossover(parents, mutation_rate):
        """
        交叉操作，从父代中随机选择基因生成新的基因序列。

        参数：
        parents (list): 包含两个CellGenetics对象的列表，代表父代细胞。
        """
        new_code = []
        for i in range(82):
            parent = random.choice(parents)
            new_code.append(parent.genetic_code[i])
        return CellGenetics.mutate(new_code, mutation_rate)

    def encode_gene(self):
        """
        将基因编码为二进制字符串。

        返回：
        str: 82位二进制字符串。
        """
        return ''.join(str(bit) for bit in self.genetic_code)

    @staticmethod
    def mutate(code, mutation_rate):
        """
        对基因进行突变操作，每个位以mutation_rate的概率翻转。

        参数：
        code (list): 基因序列。

        返回：
        list: 突变后的基因序列。
        """
        base_mutation_rate = 0.0005
        effective_mutation_rate = min(1.0, max(0.0, base_mutation_rate * mutation_rate))
        for i in range(len(code)):
            if random.random() < effective_mutation_rate:
                code[i] ^= 1
        return code

    def decode_gene(self):
        """
        解码基因序列为字典，包含性状的值和描述。

        返回：
        dict: 包含每个性状的字典，格式为 {'trait': {'value': value, 'description': description}}。
        """
        traits = {}
        for trait, (start, end) in self.GENE_SEGMENTS.items():
            traits[trait] = {
                'value': self._decode_segment(trait, start, end),
                'description': self._get_description(trait)
            }
        return traits

    def _decode_segment(self, trait, start, end):
        value = int(''.join(map(str, self.genetic_code[start:end])), 2)
        if trait in ['autotrophic_heterotrophic', 'defense_offense', 'attract_repel']:
            # 处理有符号整数
            if value & (1 << (end - start - 1)):
                value = value - (1 << (end - start))
        # 校验基因段长度是否满足参数取值范围要求
        if trait == 'energy':
            value = max(0, min(value, 1000))  # 确保能量值在0-1000范围内

        elif trait == 'low_metabolism_high_metabolism':
            value = max(1, min(value, 63))  # Ensure value is within [1,63] range
            # 代谢率影响繁殖速度，代谢率越小繁殖越慢
            # 繁殖间隔代数=64/代谢率（向下取整）
            # 代谢率值越大，繁殖间隔越小（繁殖越快）
            reproduction_interval = 64 // value
            value = reproduction_interval
        elif trait == 'mutation_rate':
            if value < 0 or value > 63:
                raise ValueError("Mutation rate value out of range [0, 63]")
        elif trait == 'size':
            if value < 0 or value > 63:
                raise ValueError("Size value out of range [0, 63]")
        elif trait == 'move_energy_cost':
            if value < 0 or value > 63:
                raise ValueError("Move energy cost value out of range [0, 63]")
        elif trait == 'static_motion':
            value = max(0, min(value%5, 5))  # 限制运动值在0-5之间
        elif trait == 'mutation_rate':
            if value < 0 or value > 63:
                raise ValueError("Mutation rate value out of range [0, 63]")
            # 获取当前细胞的代谢率，将代谢率作为突变率的乘数因子，计算最终突变率
            metabolism_rate = self._decode_segment('low_metabolism_high_metabolism', 58, 64)
            value = min(0.01, max(0.0001, value * metabolism_rate / 63.0))
        return value

    def _get_description(self, trait):
        descriptions = {
            'autotrophic_heterotrophic': '自养-异养，值为正的细胞能产生能量，值为负的细胞能消耗能量',
            'defense_offense': '防御-进攻，值为正的生物可以消耗周围8格的能量并转移给自己，值为负的生物可以抵抗进攻',
            'static_motion': '静止-运动，值为正的生物可以移动，值为负的生物不能移动',
            'long_life_short_life': '寿命长-寿命短，值越高寿命越长',
            'attract_repel': '吸引同类-排斥同类，值为正的生物可以吸引同类，值为负的生物可以排斥同类',


            'low_metabolism_high_metabolism': '代谢速度，值越高代谢越快',
            'mutation_rate': '突变率，影响基因变异的概率',
            'size': '细胞的大小，值越高细胞越大',
            'move_energy_cost': '移动能耗，值越高每次移动消耗的能量越多'
        }
        return descriptions.get(trait, '')